package com.lyon.demo.protocol.netty.command;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.SerializeUtil;
import com.lyon.demo.protocol.api.core.RequestStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;

import java.io.Serializable;
import java.util.Objects;

/**
 * @author LeeYan9
 * @since 2022-05-10
 */
@SuppressWarnings({"unchecked", "rawtypes", "unused"})
@Getter
@Setter
public abstract class RemoteCommand<T> implements Serializable, com.lyon.demo.protocol.api.core.Command<RemoteCommand<T>> {

    protected Header header;

    protected byte[] payload;

    protected RemoteCommand() {
    }


    /**
     * 命令行长度
     *
     * @return 命令行长度
     */
    public abstract int length();

    @Override
    public long getRequestId() {
        return getHeader() != null ? getHeader().getRequestId() : -1;
    }

    @Override
    public byte getCommandType() {
        return getHeader() != null ? getHeader().getType() : -1;
    }

    @Override
    public void setCommandType(byte type) {
        getHeader().setType(type);
    }

    @Override
    public int handlerCode() {
        return getHeader().getHandlerCode();
    }

    @Override
    public int getStatus() {
        return getHeader().getStatus();
    }

    @Override
    public void getStatus(int code) {
        getHeader().setStatus(code);
    }

    public  T parseData() {
        T data = null;
        if (Objects.isNull(payload)) {
            return null;
        }

        Object deserialize = SerializeUtil.deserialize(payload);
        try {
            data = (T) deserialize;
        } catch (ClassCastException e) {
            e.printStackTrace();
        }
        return data;
    }

    public static void checkSuccess(RemoteCommand remoteCommand) {
        Assert.notNull(remoteCommand, "command not null");
        Assert.isTrue(RequestStatus.SUCCESS == remoteCommand.getStatus(), "command not null");
    }

    @SneakyThrows
    @Override
    public RemoteCommand clone() {
        RemoteCommand clone = (RemoteCommand) super.clone();
        clone.setPayload(null);
        return clone;
    }
}
